package com.example.ioc;

import com.example.annotations.Autowired;
import com.example.annotations.Component;
import com.example.beans.Consumer;
import com.example.beans.MyBean;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class IoCContainer {
    private Map<String, Object> beans = new HashMap<>();

    public void registerComponent(Object bean) {
        if (bean.getClass().isAnnotationPresent(Component.class)) {
            String beanName = bean.getClass().getSimpleName().toLowerCase(); // 简单的命名策略
            beans.put(beanName, bean);
        }
    }

    public void autoWireBeans() {
        for (Object bean : beans.values()) {
            autoWireBean(bean);
        }
    }

    private void autoWireBean(Object bean) {
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Autowired.class)) {
                field.setAccessible(true);
                String beanName = field.getType().getSimpleName().toLowerCase(); // 简单的依赖查找策略
                Object dependency = beans.get(beanName);
                if (dependency != null) {
                    try {
                        field.set(bean, dependency);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException("Failed to inject dependency", e);
                    }
                } else {
                    throw new RuntimeException("Dependency not found: " + beanName);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getBean(Class<T> clazz) {
        for (Object bean : beans.values()) {
            if (clazz.isInstance(bean)) {
                return (T) bean;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        IoCContainer container = new IoCContainer();
        container.registerComponent(new MyBean());
        container.registerComponent(new Consumer());
        container.autoWireBeans();

        Consumer consumer = container.getBean(Consumer.class);
        consumer.consume();
    }
}